﻿using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyLib.Web.UI {
	/// <summary>
	/// 
	/// </summary>
	[ToolboxData("<{0}:MyGridView runat=\"server\"></{0}:MyGridView>")]
	public class MyGridView : GridView {
		/// <summary>
		/// 
		/// </summary>
		private const GridLines DefaultGridLines = GridLines.None;

		/// <summary>
		/// 
		/// </summary>
		private const string DefaultPagerDigestFormat = @"({0}-{1})/{2}";

		private Style m_pagerContentStyle;

		private Style m_pagerDigestStyle;

		/// <summary>
		/// 
		/// </summary>
		[Description("DataControls_AutoGenerateColumns")]
		[DefaultValue(true)]
		[Category("Behavior")]
		public override bool AutoGenerateColumns {
			get {
				var obj = ViewState["AutoGenerateColumns"];
				if (obj == null) {
					return false;
				} else {
					return (bool)obj;
				}
			}
			set {
				ViewState["AutoGenerateColumns"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Description("DataControls_AllowPaging")]
		[DefaultValue(true)]
		[Category("Behavior")]
		public override bool AllowPaging {
			get {
				var obj = ViewState["AllowPaging"];
				if (obj == null) {
					return true;
				} else {
					return (bool)obj;
				}
			}
			set {
				ViewState["AllowPaging"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Description("DataControls_CurrencyScale")]
		[DefaultValue(true)]
		[Category("Behavior")]
		public virtual int CurrencyScale {
			get {
				var obj = ViewState["CurrencyScale"];
				if (obj == null) {
					return 1;
				} else {
					return (int)obj;
				}
			}
			set {
				ViewState["CurrencyScale"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Description("DataControls_CurrencyScale")]
		[DefaultValue(true)]
		[Category("Behavior")]
		public virtual int AmountScale {
			get {
				var obj = ViewState["AmountScale"];
				if (obj == null) {
					return 1;
				} else {
					return (int)obj;
				}
			}
			set {
				ViewState["AmountScale"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Category("Appearance")]
		[Description("DataControls_GridLines")]
		public override GridLines GridLines {
			get {
				var obj = ViewState["GridLines"];
				if (obj == null) {
					return DefaultGridLines;
				} else {
					return (GridLines)obj;
				}
			}
			set {
				ViewState["GridLines"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Category("Appearance")]
		[Description("View_EmptyDataText")]
		[DefaultValue("")]
		[Localizable(true)]
		public override string EmptyDataText {
			get {
				var obj = ViewState["EmptyDataText"];
				if (obj == null) {
					return Properties.Main.EmptyDataText;
				} else {
					return (string)obj;
				}
			}
			set {
				ViewState["EmptyDataText"] = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Description("View_PagerDigestFormat")]
		[DefaultValue(DefaultPagerDigestFormat)]
		[Localizable(true)]
		[Category("Appearance")]
		public virtual string PagerDigestFormat {
			get {
				var obj = ViewState["PagerDigestFormat"];
				if (obj == null) {
					return DefaultPagerDigestFormat;
				} else {
					return (string)obj;
				}
			}
			set {
				ViewState["PagerDigestFormat"] = value;
			}
		}

		///// <summary>
		///// 
		///// </summary>
		//[Category("Appearance")]
		//[Bindable(false)]
		//[Themeable(true)]
		//[DefaultValue("")]
		//public string PagerCssClass {
		//    get {
		//        var obj = ViewState["PagerCssClass"];
		//        if (obj == null) {
		//            return "";
		//        } else {
		//            return (string)obj;
		//        }
		//    }
		//    set {
		//        ViewState["PagerCssClass"] = value;
		//    }
		//}

		///// <summary>
		///// 
		///// </summary>
		//[Category("Appearance")]
		//[Bindable(false)]
		//[Themeable(true)]
		//[DefaultValue("")]
		//public string PagerDigestCssClass {
		//    get {
		//        var obj = ViewState["PagerDigestCssClass"];
		//        if (obj == null) {
		//            return "";
		//        } else {
		//            return (string)obj;
		//        }
		//    }
		//    set {
		//        ViewState["PagerDigestCssClass"] = value;
		//    }
		//}

		/// <summary>
		/// 
		/// </summary>
		[Category("Styles")]
		[NotifyParentProperty(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		[Description("MyGridView_PagerContentStyle")]
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public Style PagerContentStyle {
			get {
				if (this.m_pagerContentStyle == null) {
					this.m_pagerContentStyle = new Style();
					if (base.IsTrackingViewState) {
						((IStateManager)this.m_pagerContentStyle).TrackViewState();
					}
				}
				return this.m_pagerContentStyle;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		[Category("Styles")]
		[NotifyParentProperty(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		[Description("MyGridView_PagerDigestStyle")]
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public Style PagerDigestStyle {
			get {
				if (this.m_pagerDigestStyle == null) {
					this.m_pagerDigestStyle = new Style();
					if (base.IsTrackingViewState) {
						((IStateManager)this.m_pagerDigestStyle).TrackViewState();
					}
				}
				return this.m_pagerDigestStyle;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected override Style CreateControlStyle() {
			return new TableStyle {
				// BorderStyle = System.Web.UI.WebControls.BorderStyle.None,
				GridLines = DefaultGridLines
				// CellSpacing = 0
			};
		}

		private TableRowSection m_lastRowSection = TableRowSection.TableHeader;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="row"></param>
		/// <param name="fields"></param>
		protected override void InitializeRow(GridViewRow row, DataControlField[] fields) {
			base.InitializeRow(row, fields);

			if (row.RowType == DataControlRowType.Header || row.RowType == DataControlRowType.EmptyDataRow) {
				row.TableSection = TableRowSection.TableHeader;
			} else if (row.RowType == DataControlRowType.Footer) {
				row.TableSection = TableRowSection.TableFooter;
				m_lastRowSection = TableRowSection.TableFooter;
			} else if (row.RowType == DataControlRowType.Pager) {
				row.TableSection = m_lastRowSection;
			} else {
				row.TableSection = TableRowSection.TableBody;
				m_lastRowSection = TableRowSection.TableBody;
			}
		} // end of InitializeRow.

		/// <summary>
		/// 
		/// </summary>
		/// <param name="container"></param>
		/// <param name="pagedDataSource"></param>
		private void CreatePagerRowContent(Control container, PagedDataSource pagedDataSource) {
			const string EmptyHref = "javascript:void(0)";

			PagerSettings pagerSettings = this.PagerSettings;
			int pageCount = pagedDataSource.PageCount;
			int currentPageIndex = pagedDataSource.CurrentPageIndex + 1;
			int pageButtonCount = pagerSettings.PageButtonCount;

			var firstPageIndex = (int)System.Math.Floor(currentPageIndex - (pageButtonCount / 2D) + 1D);
			if (firstPageIndex < 1) {
				firstPageIndex = 1;
			}
			var lastPageIndex = firstPageIndex + pageButtonCount - 1;
			if (lastPageIndex > pageCount) {
				lastPageIndex = pageCount;
			}

			if (firstPageIndex > 1) {
				// Add 'First' button.
				var li1 = new WebControl(HtmlTextWriterTag.Li);

				var lb1 = new System.Web.UI.HtmlControls.HtmlAnchor();
				lb1.HRef = EmptyHref;
				lb1.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(this, string.Concat("Page$", 1));
				lb1.InnerText = "<<";

				li1.Controls.Add(lb1);

				container.Controls.Add(li1);
			}

			if (currentPageIndex > 1) {
				// Add 'Prev' button.
				var li2 = new WebControl(HtmlTextWriterTag.Li);

				var lb2 = new System.Web.UI.HtmlControls.HtmlAnchor();
				lb2.HRef = EmptyHref;
				lb2.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(this, string.Concat("Page$", currentPageIndex - 1));
				lb2.InnerText = "<";

				li2.Controls.Add(lb2);

				container.Controls.Add(li2);
			}

			for (var i = firstPageIndex; i <= lastPageIndex; ++i) {
				var li = new WebControl(HtmlTextWriterTag.Li);
				if (i == currentPageIndex) {
					li.CssClass = "active";
					var sp = new MyLiteral();
					sp.Text = i.ToString();

					li.Controls.Add(sp);
				} else {
					var lb = new System.Web.UI.HtmlControls.HtmlAnchor();
					lb.HRef = EmptyHref;
					lb.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(this, string.Concat("Page$", i));
					lb.InnerText = i.ToString();

					li.Controls.Add(lb);
				}

				container.Controls.Add(li);
			}

			if (currentPageIndex < pageCount) {
				// Add 'Next' button.
				var li1 = new WebControl(HtmlTextWriterTag.Li);

				var lb1 = new System.Web.UI.HtmlControls.HtmlAnchor();
				lb1.HRef = EmptyHref;
				lb1.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(this, string.Concat("Page$", currentPageIndex + 1));
				lb1.InnerText = ">";

				li1.Controls.Add(lb1);

				container.Controls.Add(li1);
			}

			if (lastPageIndex < pageCount) {
				// Add 'Last' button.
				var li2 = new WebControl(HtmlTextWriterTag.Li);

				var lb2 = new System.Web.UI.HtmlControls.HtmlAnchor();
				lb2.HRef = EmptyHref;
				lb2.Attributes["onclick"] = Page.ClientScript.GetPostBackEventReference(this, string.Concat("Page$", pageCount));
				lb2.InnerText = ">>";

				li2.Controls.Add(lb2);

				container.Controls.Add(li2);
			}

			// Add digest.
			var firstIndex = pagedDataSource.CurrentPageIndex * pagedDataSource.PageSize + 1;
			var lastIndex = firstIndex + pagedDataSource.PageSize - 1;
			var totalCount = pagedDataSource.DataSourceCount;
			if (pagedDataSource.IsLastPage) {
				lastIndex = totalCount;
			}

			var digest = new WebControl(HtmlTextWriterTag.Li);
			digest.MergeStyle(PagerDigestStyle);

			var digestc = new MyLiteral();
			digestc.Text = string.Format(PagerDigestFormat, firstIndex, lastIndex, totalCount);
			digest.Controls.Add(digestc);

			container.Controls.Add(digest);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="row"></param>
		/// <param name="columnSpan"></param>
		/// <param name="pagedDataSource"></param>
		protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource) {
			base.InitializePager(row, columnSpan, pagedDataSource);

			row.TableSection = m_lastRowSection;

			if (!AllowPaging)
				return;

			var cell = row.Cells[0];

			System.Diagnostics.Debug.Assert(cell != null);

			cell.Controls.Clear();

			var pgWrapper = new WebControl(HtmlTextWriterTag.Div);
			pgWrapper.MergeStyle(PagerContentStyle);

			var pgUl = new WebControl(HtmlTextWriterTag.Ul);

			CreatePagerRowContent(pgUl, pagedDataSource);

			pgWrapper.Controls.Add(pgUl);
			cell.Controls.Add(pgWrapper);

			/*
			var itable = cell.Controls[0] as Table;
			if (itable == null)
				return;

			var firstIndex = pagedDataSource.CurrentPageIndex * pagedDataSource.PageSize + 1;
			var lastIndex = firstIndex + pagedDataSource.PageSize - 1;
			var totalCount = pagedDataSource.DataSourceCount;
			if (pagedDataSource.IsLastPage) {
				lastIndex = totalCount;
			}

			var irow = itable.Rows[0];
			var rcell = new TableCell();
			if (PagerDigestStyle != null) {
				rcell.MergeStyle(PagerDigestStyle);
			}
			rcell.Text = string.Format("({0}-{1}/{2})", firstIndex, lastIndex, totalCount);
			irow.Cells.Add(rcell);
			 */
		} // end of InitializePager.

		/// <summary>
		/// 
		/// </summary>
		protected override void PerformSelect() {
			Context.ExecuteSafely(base.PerformSelect);
		} // end of PerformSelect.
	} // end of MyGridView.
}
